﻿using XUCore.WeChat.Apis.Token;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;

namespace XUCore.WeChat
{
    /// <summary>
    /// 公众号js ticket管理器
    /// </summary>
    public class WeChatTicketManager : IWeChatTicketManager
    {
        private readonly WeChatFuncs weChatFuncs;
        private readonly IServiceProvider serviceProvider;
        private readonly IWeChatTokenManager tokenManager;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="weChatFuncs"></param>
        /// <param name="tokenManager"></param>
        /// <param name="serviceProvider"></param>
        public WeChatTicketManager(WeChatFuncs weChatFuncs, IWeChatTokenManager tokenManager, IServiceProvider serviceProvider)
        {
            this.weChatFuncs = weChatFuncs;
            this.serviceProvider = serviceProvider;
            this.tokenManager = tokenManager;
        }

        /// <summary>
        /// 获取ticket
        /// </summary>
        /// <param name="app">应用标识</param>
        /// <returns></returns>
        public virtual async Task<string> GetTicketAsync(string app)
        {
            var options = weChatFuncs.GetWeChatOptions(app);

            if (options == null)
                throw new WeChatSdkException($"{nameof(WeChatTicketManager)}，App:{app}，获取微信配置失败。");

            string ticket = weChatFuncs.GetTicketByAppId(options.AppId);

            if (string.IsNullOrEmpty(ticket))
            {
                var accessToken = await tokenManager.GetAccessTokenAsync(app);

                var ticketApi = serviceProvider.GetService<ITicketApi>();
                var result = await ticketApi.GetAsync(accessToken);
                if (!result.IsSuccess())
                {
                    throw new WeChatSdkException(result.Message);
                }
                weChatFuncs.CacheTicket(options.AppId, result.Ticket);
                return result.Ticket;
            }

            return ticket;
        }
    }

}
